package top.lixunda.ecommerce.server.user.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.OrderByDTO;
import top.lixunda.ecommerce.server.user.api.entity.db.RoleDO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 角色查询DTO
 *
 * @author lixunda
 * @version time:2020/4/26 13:53
 */
@ApiModel("角色查询DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class RoleQueryDTO extends OrderByDTO implements ILambdaQueryWrapperDTO<RoleDO> {

    /**
     * 角色编号
     */
    @ApiModelProperty("角色编号")
    private List<Integer> roleId;

    /**
     * 角色所属管理类型，STORE 和 ADMIN
     */
    @ApiModelProperty("角色所属管理类型，STORE 和 ADMIN")
    private List<String> manageType;

    /**
     * 店铺编号，当 Type=STORE 时有效
     */
    @ApiModelProperty("店铺编号，当 Type=STORE 时有效")
    private List<Integer> storeId;

    /**
     * 店铺名称，当 Type=STORE 时有效
     */
    @ApiModelProperty("店铺名称，当 Type=STORE 时有效")
    private List<String> storeName;

    /**
     * 角色名称
     */
    @ApiModelProperty("角色名称")
    private List<String> roleName;

    /**
     * 角色有效开始时间，时间段以为将无法享受角色权限
     */
    @ApiModelProperty("角色有效开始时间，时间段以为将无法享受角色权限")
    private LocalDateTime roleBeginTimeBegin;

    /**
     * 角色有效开始时间，时间段以为将无法享受角色权限
     */
    @ApiModelProperty("角色有效开始时间，时间段以为将无法享受角色权限")
    private LocalDateTime roleBeginTimeEnd;

    /**
     * 角色有效结束时间，时间段以为将无法享受角色权限
     */
    @ApiModelProperty("角色有效结束时间，时间段以为将无法享受角色权限")
    private LocalDateTime roleEndTimeBegin;

    /**
     * 角色有效结束时间，时间段以为将无法享受角色权限
     */
    @ApiModelProperty("角色有效结束时间，时间段以为将无法享受角色权限")
    private LocalDateTime roleEndTimeEnd;

    /**
     * 是否是店铺使用角色，如店铺超级管理员角色，普通店铺管理员角色
     */
    @ApiModelProperty("是否是店铺使用角色，如店铺超级管理员角色，普通店铺管理员角色")
    private Integer storeEmploy;

    /**
     * 是否固化角色，固化的角色不能修改或必须另外的特殊接口进行修改，防止出错
     */
    @ApiModelProperty("是否固化角色，固化的角色不能修改或必须另外的特殊接口进行修改，防止出错")
    private Integer solidifyFlag;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeBegin;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeEnd;

    /**
     * 创建人员编号
     */
    @ApiModelProperty("创建人员编号")
    private List<Integer> createUserId;

    /**
     * 创建人员类型
     */
    @ApiModelProperty("创建人员类型")
    private List<String> createUserType;

    /**
     * 排序映射字段
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private static final Map<String, SFunction<RoleDO, ?>> COLUMNS =
            new ImmutableMap.Builder<String, SFunction<RoleDO, ?>>()
                    .put("roleId", RoleDO::getRoleId)
                    .put("manageType", RoleDO::getManageType)
                    .put("storeId", RoleDO::getStoreId)
                    .put("storeName", RoleDO::getStoreName)
                    .put("roleName", RoleDO::getRoleName)
                    .put("roleDesc", RoleDO::getRoleDesc)
                    .put("roleBeginTime", RoleDO::getRoleBeginTime)
                    .put("roleEndTime", RoleDO::getRoleEndTime)
                    .put("storeEmploy", RoleDO::getStoreEmploy)
                    .put("solidifyFlag", RoleDO::getSolidifyFlag)
                    .put("createTime", RoleDO::getCreateTime)
                    .put("createUserId", RoleDO::getCreateUserId)
                    .put("createUserName", RoleDO::getCreateUserName)
                    .put("createUserType", RoleDO::getCreateUserType)
                    .put("remark", RoleDO::getRemark)
                    .build();


    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @Override
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public LambdaQueryWrapper<RoleDO> toWrapper() {
        LambdaQueryWrapper<RoleDO> wrapper = new LambdaQueryWrapper<>();
        if (ObjectValidators.isNotEmpty(roleId)) {
            wrapper.and(innerWrapper -> roleId.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getRoleId, item)));
        }
        if (ObjectValidators.isNotEmpty(manageType)) {
            wrapper.and(innerWrapper -> manageType.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getManageType, item)));
        }
        if (ObjectValidators.isNotEmpty(storeId)) {
            wrapper.and(innerWrapper -> storeId.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getStoreId, item)));
        }
        if (ObjectValidators.isNotEmpty(storeName)) {
            wrapper.and(innerWrapper -> storeName.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getStoreName, item)));
        }
        if (ObjectValidators.isNotEmpty(roleName)) {
            wrapper.and(innerWrapper -> roleName.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getRoleName, item)));
        }
        if (ObjectValidators.isNotEmpty(roleBeginTimeBegin)) {
            wrapper.ge(RoleDO::getRoleBeginTime, roleBeginTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(roleBeginTimeEnd)) {
            wrapper.le(RoleDO::getRoleBeginTime, roleBeginTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(roleEndTimeBegin)) {
            wrapper.ge(RoleDO::getRoleEndTime, roleEndTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(roleEndTimeEnd)) {
            wrapper.le(RoleDO::getRoleEndTime, roleEndTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(storeEmploy)) {
            wrapper.eq(RoleDO::getStoreEmploy, storeEmploy);
        }
        if (ObjectValidators.isNotEmpty(solidifyFlag)) {
            wrapper.eq(RoleDO::getSolidifyFlag, solidifyFlag);
        }
        if (ObjectValidators.isNotEmpty(createTimeBegin)) {
            wrapper.ge(RoleDO::getCreateTime, createTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(createTimeEnd)) {
            wrapper.le(RoleDO::getCreateTime, createTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(createUserId)) {
            wrapper.and(innerWrapper -> createUserId.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getCreateUserId, item)));
        }
        if (ObjectValidators.isNotEmpty(createUserType)) {
            wrapper.and(innerWrapper -> createUserType.forEach(item ->
                    innerWrapper.or().eq(RoleDO::getCreateUserType, item)));
        }
        dealWithOrderBy(wrapper, COLUMNS);
        return wrapper;
    }
}
